#include <iostream>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <sys/syscall.h>
#include <unistd.h>

using namespace std;

// 只要是带了__thread，可以理解成将这个全局变量都拷贝一份给对应的线程，所以每个线程都有自己的
int global_value = 100;

void *startRoutine(void *args)
{
    // 线程分离:（自己分离自己）
    pthread_detach(pthread_self());
    cout << "线程分离了....." << endl;

    while (true)
    {
        cout << "thread " << pthread_self() << " global_value: "
             << global_value << " &global_value: " << &global_value << " Inc: " << global_value++
             << " lwp " << syscall(SYS_gettid) << endl;

        sleep(1);
    }

    // 退出进程，任何一个线程调用exit，都表示整个进程退出
    // exit(1);
    // pthread_exit()
}

int main()
{
    pthread_t tid1;
    pthread_t tid2;
    pthread_t tid3;

    pthread_create(&tid1, nullptr, startRoutine, (void *)"thread1");
    pthread_create(&tid2, nullptr, startRoutine, (void *)"thread2");
    pthread_create(&tid3, nullptr, startRoutine, (void *)"thread3");

    // sleep之后才能看到join失败的情况
    // sleep是为了这三个线程都detach之后再进行分离
    sleep(5);

    // 因为主线程和新线程谁先被调度是不一定的，有可能，join先被阻塞挂起了，而新线程还没有detach
    // 更倾向于：让主线程，分离其他线程

    pthread_detach(tid1);
    pthread_detach(tid2);
    pthread_detach(tid3);

    // 1. 立即分离(压根不关系线程执行的怎么样)，延后分离(线程跑一段时间后再分离) -- 必须保证线程活着 -- 意味着，我们不再关心这个线程的死活。4. 线程退出的第四种方式，延后退出
    // 2. 新线程分离，但是主线程先退出(进程退出) -- 一般我们分离线程，对应的main thread一般不要退出(常驻内存的进程)
    // 一旦主线程退出了，所有新线程也会跟着释放，主线程退出代表进程退出，地址空间页表，代码数据等都会释放
    // 新线程退出了不会影响进程的继续运行
    // 线程分离了，线程退出就会自动被系统回收

    // int n = pthread_join(tid1, nullptr);
    // cout << n << ":" << strerror(n) << endl;
    // pthread_join(tid2, nullptr);
    // cout << n << ":" << strerror(n) << endl;
    // pthread_join(tid3, nullptr);
    // cout << n << ":" << strerror(n) << endl;

    return 0;
}